import { Request, Response } from 'express';
import { z } from 'zod';

import { ProjectModel } from '../../../models/project';
import { ScriptModel } from '../../../models/script';
import resp from '../../../utils/response';
import { deleteProjectDirectory, getRelatedScriptsCount } from '../utils';

// 删除应用参数校验
export const validator = z.object({
  id: z.string().regex(/^[0-9a-fA-F]{24}$/, '项目ID格式不正确'),
});

/**
 * 删除项目接口
 * @description 删除指定ID的项目，包括关联的脚本和文件夹
 * @route DELETE /api/project/:id
 * @param req Express请求对象
 * @param res Express响应对象
 * @returns Promise<Response> 删除结果响应
 *
 * @example
 * DELETE /api/project/507f1f77bcf86cd799439011
 *
 * 成功响应:
 * {
 *   "success": true,
 *   "code": 200,
 *   "message": "项目删除成功",
 *   "data": {
 *     "deletedProject": {
 *       "_id": "507f1f77bcf86cd799439011",
 *       "name": "示例项目",
 *       "apps": [],
 *       "remark": "这是一个示例项目",
 *       "scripts": [],
 *       "createdAt": "2024-01-01T00:00:00.000Z",
 *       "updatedAt": "2024-01-01T00:00:00.000Z"
 *     },
 *     "deletedScriptsCount": 3,
 *     "directoryDeleted": true
 *   }
 * }
 */
export async function api(req: Request, res: Response): Promise<Response> {
  try {
    const { id } = req.params as z.infer<typeof validator>;

    // 查找要删除的项目
    const projectToDelete = await ProjectModel.findById(id);
    if (!projectToDelete) {
      return resp.error(res, 404, '项目不存在');
    }

    // 检查关联脚本数量
    const relatedScriptsCount = await getRelatedScriptsCount(id);

    // 删除关联的脚本
    let deletedScriptsCount = 0;
    if (relatedScriptsCount > 0) {
      const deleteScriptsResult = await ScriptModel.deleteMany({ projectId: id });
      deletedScriptsCount = deleteScriptsResult.deletedCount || 0;
    }

    // 删除项目
    await ProjectModel.findByIdAndDelete(id);

    // 异步删除项目文件夹（不影响响应）
    const directoryDeletePromise = deleteProjectDirectory(id);

    // 等待文件夹删除完成（设置超时以避免长时间等待）
    let directoryDeleted = false;
    try {
      await Promise.race([
        directoryDeletePromise,
        new Promise((_, reject) => setTimeout(() => reject(new Error('删除超时')), 5000)),
      ]);
      directoryDeleted = true;
    } catch (error) {
      console.error(`项目 ${id} 文件夹删除失败或超时:`, error);
      // 继续异步删除，不阻塞响应
      directoryDeletePromise.catch(err => {
        console.error(`项目 ${id} 文件夹异步删除失败:`, err);
      });
    }

    const responseData = {
      deletedProject: projectToDelete,
      deletedScriptsCount,
      directoryDeleted,
    };

    console.log(
      `项目删除成功: ${projectToDelete.name} (ID: ${id}), 删除脚本数量: ${deletedScriptsCount}`,
    );
    return resp.success(res, responseData, '项目删除成功');
  } catch (error) {
    console.error('删除项目失败:', error);
    return resp.catch(res, error);
  }
}
